/******************************************************************************中
 * @brief: file  : systask.c
 * @Author:   aple
 * @Date: 2022-12-14 18:06:21
 * @LastEditors: aple
 * @LastEditTime: 2023-02-27 16:06:54
 * @Verision: 1.0.0.0
 ******************************************************************************/
#define _SYSTASK_MODULE_
#include "os_obj.h"
#include "sys_task.h"
#include "bsp.h"
#include "pincfg.h"
#include "nor_cmd.h"
#include "framework.h"
#include "mem_alloc.h"

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/

/*****************************************************************************
 * @brief   var.
 *****************************************************************************/
class pin_ndef_class *pin_led1;
class pin_ndef_class *pin_led2;

/*****************************************************************************
 * @brief   fun.
 *****************************************************************************/
extern "C"
{
	void task_system(const void *argument);
}

/*****************************************************************************
 * @brief   system task.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void task_system(const void *argument)
{
	uint32_t tick;
	uu8 *buff;

	thread_create();

	sys_app_init();

	buff = (uu8 *)mem_eram.api->malloc(2048);
	memset(buff, 0x33, 2048);
	mem_eram.api->free(buff);

	while (1)
	{
		buff = (uu8 *)mem_ccm.api->malloc(256);

		Gst.info.stack_used = stack_used();

		Gst.u_tick = app_tick_get();

		// 虚拟RTC
		copy_u8(&Gst.pulse, buff, sizeof(Gst.pulse));
		pulse_creat((timer_pulse_type *)buff, Gst.u_tick);
		copy_u8(buff, &Gst.pulse, sizeof(Gst.pulse));

		if (Gst.pulse.pulse_1s)
		{
			TimeRun(&Gst.rtc_time);
		}

		sys_app_run_once();

		tick = app_tick_get();
		Gst.bsp_dly_verify = app_tick_get() - tick;

		NOP1();
		osDelay(ms_ticks(10));
		NOP1();

		mem_ccm.api->free(buff);
	}
}

/*****************************************************************************
 * @brief   led control.
 *****************************************************************************/
obj_app_order(sys_led_ctr);
void sys_led_ctr(void)
{
	o_led1.out(Gst.pulse.wave_250ms);
	o_led2.out(Gst.pulse.wave_125ms);
}

/*****************************************************************************
 * @brief   led control.
 *****************************************************************************/
obj_app_order(sys_beep_ctr);
void sys_beep_ctr(void)
{
	beep_handle(&Gst.bios.beep, Gst.pulse.pulse_50ms);

	beep.out(Gst.bios.beep.b_beep_st);
}

/*****************************************************************************
 * @brief   led control.
 *****************************************************************************/
obj_app_order(sys_key);
void sys_key(void)
{
	// sample
	io_flt_extv2(&Gst.bios.key_up, 1, Gst.pulse.pulse_100ms, 2, key_up.in_st());
	io_flt_extv2(&Gst.bios.key[0], 1, Gst.pulse.pulse_100ms, 2, key_0.in_st());
	io_flt_extv2(&Gst.bios.key[1], 1, Gst.pulse.pulse_100ms, 2, key_1.in_st());
	io_flt_extv2(&Gst.bios.key[2], 1, Gst.pulse.pulse_100ms, 2, key_2.in_st());
}

/*****************************************************************************
 * @brief   touch
 *****************************************************************************/
obj_app_order(touch_handle);
void touch_handle(void)
{
	// signal
	io_signal_info_handle(&Gst.bios.tp, Gst.pulse.pulse_100ms, tp_st_get() > 0 ? 1 : 0);

	if (Gst.bios.tp.edge_found)
	{
		dbg_print("touch press !" PTCR);
	}

	if (Gst.bios.tp.edge_lost)
	{
		dbg_print("touch release !" PTCR);
	}
}

/*****************************************************************************
 * @brief   flash opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
obj_init_order5(sys_flash_init);
void sys_flash_init(void)
{
	extern const spi_flash_hal_type spi_nor;

	osMutexAcquire(os_obj.mid_nor_spi, INT16_MAX);

	nor_init(&spi_nor, 0);

	nor_id_read(Gst.flash.nor_id);

	osMutexRelease(os_obj.mid_nor_spi);

	dbg_print("flash id: %02X %02X %02X \n", Gst.flash.nor_id[0], Gst.flash.nor_id[1], Gst.flash.nor_id[2]);
}

/*******************************************************************************
 * @brief: nor test
 * @param argc
 * @param *argv
 * @return {*}
 ******************************************************************************/
int nor_test(int argc, char *argv[])
{
	uu8 *buff, er = 0, rd = 0, wr = 0;
	uu32 addr = 1 * 1024 * 1024, len = 128;

	// 操作方式
	if (argc >= 2)
	{
		char *str = argv[1];

		if (str[0] == 'e')
			er = 1;
		if (str[0] == 'r')
			rd = 1;
		if (str[0] == 'w')
			wr = 1;
	}
	else
	{
		er = 1;
		wr = 1;
		rd = 1;
	}

	// 操作地址
	if (argc >= 3)
	{
		addr = atoi(argv[2]) * 1024;
	}

	// 操作数量
	if (argc >= 4)
	{
		len = atoi(argv[3]);
	}

	// 操作
	buff = (uu8 *)malloc(len + 20);

	osMutexAcquire(os_obj.mid_nor_spi, INT16_MAX);

	if (er)
	{
		nor_block_erase(addr);
		dbg_print("erase flash : 0X%08X\n", addr);
	}

	if (wr)
	{
		loop(len)
			buff[index] = index;

		nor_write_multi(addr, len, buff);

		dbg_print("write flash : 0X%08X\n", addr);
	}

	if (rd)
	{
		loop(len)
			buff[index] = 0;

		nor_read(addr, len, buff);

		dbg_print("read flash : 0X%08X\n", addr);
		dbg_u8_print("NOR READ:\n", buff, len, 16);
	}

	osMutexRelease(os_obj.mid_nor_spi);

	free(buff);

	return 0;
}
DBG_FUNX_EXPORT(nor_test, "e/r/w [A] [L]");

/*****************************************************************************
 * @brief   iic opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
DBG_FUN_EXPORT(sw_iic_opt);
int sw_iic_opt(int argc, char **argv)
{
	uint8_t buff[64];

	sw_iic_init(sw_iic);
	at24_hal_link(&at24_obj);

	loop(64)
		buff[index] = index + 32;

	at24_write(0, 64, buff);

	loop(64)
		buff[index] = 0;

	at24_read(0, 64, buff);

	dbg_u8_print("at data\n", buff, 64, 16);

	return 0;
}

/*****************************************************************************
 * @brief   iic opt.
 *
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
DBG_FUNX_EXPORT(beep_req, "[ent] [dist] [cnt]");
int beep_req(int argc, char **argv)
{
	ii08 ent = 1, dist = 1, cnt = 1;

	if (argc >= 2)
		ent = atoi(argv[1]) / 50;

	if (argc >= 3)
		dist = atoi(argv[2]) / 50;

	if (argc >= 4)
		cnt = atoi(argv[3]);

	rang_limit(ent, 1, 100);
	rang_limit(dist, 1, 100);
	rang_limit(cnt, 1, 100);

	beep_auto_req(&Gst.bios.beep, cnt, ent + dist, ent);

	return 0;
}
